import io
import wave
import subprocess

def pcm2wav(pcm, framerate, nchannels=1, sampwidth=2):
    with io.BytesIO() as f:
        with wave.open(f, "wb") as wf:
            wf.setframerate(framerate)
            wf.setnchannels(nchannels)
            wf.setsampwidth(sampwidth)
            wf.writeframes(pcm)
        wav = f.getvalue()
        return wav

def wav2pcm(wav):
    with io.BytesIO(wav) as f:
        with wave.open(f, "rb") as wf:
            framerate = wf.getframerate()
            nchannels = wf.getnchannels()
            sampwidth = wf.getsampwidth()
            frames = wf.readframes(wf.getnframes())
        return frames, framerate, nchannels, sampwidth

def pcm2mp3(pcm, framerate, nchannels=1, sampwidth=2):
    wav = pcm2wav(pcm, framerate, nchannels, sampwidth)
    with subprocess.Popen(["ffmpeg", "-i", "-", "-f", "mp3", "-"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) as p:
        out, _ = p.communicate(input=wav)
    return out

def mp32pcm(mp3):
    with subprocess.Popen(["ffmpeg", "-i", "-", "-f", "s16le", "-"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) as p:
        out, _ = p.communicate(input=mp3)
    frames, framerate, nchannels, sampwidth = wav2pcm(out)
    return frames, framerate, nchannels, sampwidth

def pcm2ogg(pcm, framerate, nchannels=1, sampwidth=2):
    wav = pcm2wav(pcm, framerate, nchannels, sampwidth)
    with subprocess.Popen(["ffmpeg", "-i", "-", "-f", "ogg", "-"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) as p:
        out, _ = p.communicate(input=wav)
    return out

def ogg2pcm(ogg):
    with subprocess.Popen(["ffmpeg", "-i", "-", "-f", "s16le", "-"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) as p:
        out, _ = p.communicate(input=ogg)
    frames, framerate, nchannels, sampwidth = wav2pcm(out)
    return frames, framerate, nchannels, sampwidth
